package com.apache.springboot.controller;

import com.apache.springboot.bean.Customer;
import com.apache.springboot.service.CustomerService;
import com.apache.springboot.service.impl.CustomerServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

/**
 * 控制层
 */

//@Controller  //标识为控制层 (Spring)
//升级版控制层
@RestController //@Controller + @ResponseBody
public class CustomerController {

    //直接在类中常见的对象，不好，写死了
    //CustomerServiceImpl customerService = new CustomerServiceImpl();

    //需求：更换业务层的实现，CustomerServiceNew
    //CustomerServiceNew customerService = new CustomerServiceNew();

    //单例，接口，工厂
    //接口
    //CustomerService customerService = new CustomerServiceImpl();

    //SpringBoot
    /**
     * 如果有两个类都实现了CustomerService,而又都是相同方法，那么就在@Autowired下面加入@Qualifier
     */
    @Autowired  //从Spring 容器中找到对应类型的对象，注入过来
    @Qualifier("customerServiceImpl") //明确知名哪个对象注入过来
    CustomerService customerService;

    /**
     * 客户端请求：http://localhost:8080/HelloWorld  hello world doc .....
     * <p>
     * 请求处理方法
     *
     * @RequestMapping : 将客户端的请求与方法进行映射
     * @ResponseBody : 将方法的返回值处理成字符串(JSON)返回给客户端
     */

    @RequestMapping("/hello")
    // @RequestBody
    public String hello() {
        return "hello Java";
    }

    /**
     * 请求参数 :
     *  1,地址栏中kv格式的参数
     *  2,嵌入到地址栏中的参数
     *  3,封装到请求体的参数
     */

    /**
     * 1.请求到地址栏的参数
     * <p>
     * http://localhost:8080/paramkv?username=zhangsan&age=22
     *
     * @RequestParam : 将请求参数映射到方法对相应的形参上
     * 如果请求的参数名和方法形参名一致，可以直接进行参数值的映射，直接省略改注解
     */

    @RequestMapping("/paramkv")
    public String paramkv(@RequestParam("username") String name, Integer age) {
        return "username = " + name + ", age = " + age;
    }

    /**
     * 2,嵌入到地址栏中的参数
     * <p>
     * http://localhost:8080/parampath/lisi/22?address=beijing
     *
     * @PathVariable : 将请求路径中的参数映射到请求方法对应的形参上
     */

    @RequestMapping("/parampath/{username}/{age}")
    public String paramPath(@PathVariable("username") String username, @PathVariable("age") Integer age, @RequestParam("address") String address) {
        return "username = " + username + ", age = " + age + ", address = " + address;
    }

    /**
     * 3,封装到请求体的参数
     * <p>
     * http://localhost:8080/parambody
     * <p>
     * 请求体中的参数：
     * username = hao
     * password = 123456
     *
     * 如果请求参数名与方法名的形参不一致，则需要通过@RequestParam来标识获取，如果一致，可以直接映射
     */

//    @RequestMapping("/parambody")
//    public String parambody(String username, String password) {
//        return "username = " + username + ", password = " + password;
//    }

    /**
     * 4,加入实体类的用法
     *
     * @param customer 实体类
     * @return 返回实体类
     * @RequestBody : 将请求体中的json格式的参数映射到对象对应的属性上
     */
    @RequestMapping("/parambody")
    public Customer parambody(@RequestBody Customer customer) {
        return customer; //转换成Json字符串
    }

    /**
     * 常用方式：GET，POST，PUT，DELETE ......
     * <p>
     * GET : 读
     * <p>
     * POST : 写
     * http://localhost:8080/requestmethod
     */

    //@RequestMapping(value = "/requestmethod",method = RequestMethod.GET)
    //@GetMapping("/requestmethod") //GET 请求
    @PostMapping("/requestmethod") // POST 请求
    public Customer requestmethod(@RequestBody Customer customer) {
        return customer; //转换成Json字符串
    }

    /**
     * http://localhost:8080/login?username=zhangsan&password=123456
     */

    @GetMapping("/login")
    public String login(@RequestParam("username") String username, @RequestParam("password") String password) {

        //业务处理
        //在每个方法中创建业务层对象，很不好
        //CustomerServiceImpl customerService = new CustomerServiceImpl();
        String result = customerService.doLogin(username, password);

        return result;
    }

}
